package com.atguigu.bookcity.service.impl;

import com.atguigu.bookcity.entity.Inventory;
import com.atguigu.bookcity.entity.OrderForm;
import com.atguigu.bookcity.entity.OrderItem;
import com.atguigu.bookcity.entity.User;
import com.atguigu.bookcity.entity.vo.orderVo;
import com.atguigu.bookcity.mapper.OrderMapper;
import com.atguigu.bookcity.service.InventoryService;
import com.atguigu.bookcity.service.OrderItemService;
import com.atguigu.bookcity.service.OrderService;
import com.atguigu.bookcity.vo.CommonResult;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author hxx
 * @since 2021-03-20
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, OrderForm> implements OrderService {
    @Resource
    private OrderItemService orderItemService;

    @Resource
    private InventoryService inventoryService;

    @Resource
    private OrderMapper orderMapper;

    @Override
    @Transactional
    public HashMap<String, Object> getOrderMsg(String userId) {
        List<OrderItem> orderItems = orderMapper.getOrderMsg(userId);
        HashMap<String, Object> all = new HashMap<>();
        List<OrderItem> hashMapOk =
                orderItems.stream()
                        .filter(one -> one.getStatus().equals("1"))
                        .peek(one -> {
                            one.setStatus("已支付");
                            one.setTotal(BigDecimal.valueOf(one.getBookNumber()).multiply(one.getPrice()));
                        })
                        .collect(Collectors.toList());
        List<OrderItem> hashMapError =
                orderItems.stream()
                        .filter(one -> one.getStatus().equals("0"))
                        .peek(one -> {
                            one.setStatus("未支付");
                            one.setTotal(BigDecimal.valueOf(one.getBookNumber()).multiply(one.getPrice()));
                        })
                        .collect(Collectors.toList());
        all.put("ok", hashMapOk);
        all.put("error", hashMapError);
        return all;
    }

    @Override
    @Transactional
    public Map<String, Object> createOrder(List<orderVo> orderVoList, String userId) {

        OrderForm order = new OrderForm();
        order.setStatus(0);
        order.setUserId(userId);
        save(order);//生成订单

        String orderId = order.getId();
        ArrayList<String> ids = new ArrayList<>();
        List<OrderItem> orderItems = new ArrayList<>();
        for (orderVo orderVo : orderVoList) {
            OrderItem orderItem = new OrderItem();
            BeanUtils.copyProperties(orderVo, orderItem);
            orderItem.setOrderId(orderId);
            orderItems.add(orderItem);
            ids.add(orderVo.getBookId());
        }
        List<Inventory> notEnough = new ArrayList<>();
        //  检查库存是否充足,将不能购买库存不足的书
        List<Inventory> inventories = inventoryService.listByIds(ids);
        inventories.forEach(inventory -> {
            for (OrderItem orderItem : orderItems) {
                if (orderItem.getBookId().equals(inventory.getBookId())) {
                    if (inventory.getNumber() < orderItem.getBookNumber()) {
                        // 移除库存不足的物品
                        orderItems.remove(orderItem);
                        notEnough.add(inventory);
                        break;
                    } else {
                        // 模拟 减库存，此时没有更新数据库
                        inventory.setNumber(inventory.getNumber() - orderItem.getBookNumber());
                    }
                }
            }
        });


        orderItemService.saveBatch(orderItems);
        // 更新库存表
        inventoryService.updateBatchById(inventories);
        HashMap<String, Object> map = new HashMap<>();
        map.put("items", orderItems);
        map.put("notEnoughInventories", notEnough);
        return map;
    }

    @Override
    @Transactional
    public CommonResult getRank() {

        QueryWrapper<OrderItem> wrapper = new QueryWrapper<>();

        wrapper.orderByDesc("book_number");
        wrapper.select("book_id", "book_number");


        List<OrderItem> bookIds = orderItemService.list(wrapper);

        List<orderVo> list = new ArrayList<>();
        for (OrderItem bookId : bookIds) {
            orderVo vo = new orderVo();
            BeanUtils.copyProperties(bookId, vo);
            list.add(vo);
        }
//        List<orderVo> FirstThree = toRepeat(list).subList(0, 3);
        return CommonResult.ok().data("rank", toRepeat(list));
    }

    @Override
    @Transactional
    public void deleteOrder(List<String> orderIds) {
        User user = (User) SecurityUtils.getSubject().getPrincipal();
        List<OrderItem> orderMsg = orderMapper.getOrderMsg(user.getId());

        //未支付 归还库存
        List<OrderItem> noks = orderMsg
                .stream()
                .filter(one -> one.getStatus().equals("0") && orderIds.contains(one.getOrderId()))
                .collect(Collectors.toList());
        //若没有未支付状态的，则不需归还库存
        if (noks.size() != 0) {
            List<Inventory> updateInventories;
            List<Inventory> nok = noks
                    .stream()
                    .map(one -> {
                        Inventory inventory = new Inventory();
                        inventory.setNumber(one.getBookNumber());
                        inventory.setBookId(one.getBookId());
                        return inventory;
                    })
                    .collect(Collectors.toList());
            updateInventories = inventoryService.listByIds(nok.stream()
                    .map(Inventory::getBookId)
                    .collect(Collectors.toList()))
                    .stream()
                    .peek(inventory -> {
                        for (Inventory no : nok) {
                            if (no.getBookId().equals(inventory.getBookId())) {
                                inventory.setNumber(no.getNumber() + inventory.getNumber());
                                break;
                            }
                        }
                    }).collect(Collectors.toList());
            //归还库存
            inventoryService.updateBatchById(updateInventories);
        }


        //删除订单和item
        removeByIds(orderIds);
        orderItemService.getBaseMapper().deleteBatchIds(orderIds);
    }


    //
    private static Map<String, Integer> toRepeat(List<orderVo> list) {

        //新定义一个map集合,key存在插入value，否则更新value
        HashMap<String, Integer> map = new HashMap<>();
        for (orderVo vo : list) {
            if (!map.containsKey(vo.getBookId()))
                map.put(vo.getBookId(), vo.getBookNumber());
            else {
                int value = map.get(vo.getBookId());
                int number = vo.getBookNumber();
                map.put(vo.getBookId(), (value + number));
            }
        }

        ArrayList<Integer> numbers = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            numbers.add(entry.getValue());
        }

        numbers.sort((o1, o2) -> (o2 - o1));

        String one_id = getKey(map, numbers.get(0));
        String two_id = getKey(map, numbers.get(1));
        String three_id = getKey(map, numbers.get(2));


        HashMap<String, Integer> rank = new HashMap<>();
        rank.put(three_id, numbers.get(2));
        rank.put(two_id, numbers.get(1));
        rank.put(one_id, numbers.get(0));

        return rank;
    }

    public static String getKey(Map<String, Integer> map, Integer value) {
        for (String s : map.keySet()) {
            if (map.get(s).equals(value))
                return s;
        }
        return null;
    }

}
